# 将刚才knn算法的过程进行封装

# 导入一些需要的包
import numpy as np
from math import sqrt
from collections import Counter

# 自定义的KNN算法
class KNeighborsClassifier:
    # 构造函数
    def __init__(self, k):
        self.k = k
        self.X_train = None
        self.y_train = None

    # 拟合函数(KNN的拟合-数据本身就是规律 不需要提取相关的参数)
    def fit(self,X_train, y_train):
        self.X_train = X_train
        self.y_train = y_train
        return self

    # 预测函数(X_predict待预测的特征矩阵)
    def predict(self,X_predict):
        y_predict = [self.__predict(x) for x in X_predict]
        return np.array(y_predict)

    # 预测函数(x待预测的特征向量)
    def __predict(self,x):
        distances = [sqrt(np.sum((x_train - x)**2)) for x_train in self.X_train]
        nearest = np.argsort(distances)
        topK_y = [ self.y_train[i] for i in nearest[:self.k]]
        votes = Counter(topK_y)
        return votes.most_common(1)[0][0]

    # 新建一个准确度计算
    def score(self, X_test, y_test):
        y_predict = self.predict(X_test)
        from MyMLTools.metrics import accuracy_score
        return accuracy_score(y_test,y_predict)